<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\Artisan;

use App\Common\Logs;
use Illuminate\Http\Request;
use Validator;
use Log;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public $validated;
    public $request;

    public function __construct()
    {
        $this->request = app('request');
        Log::info('request:'.json_encode($this->request->all()));

        // 初始化微信配置
        $this->config = [
            'app_id' => config('wechat.mini_program.default.app_id'),
            'secret' => config('wechat.mini_program.default.secret'),
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => storage_path('logs/wechat.log'),
            ],
        ];

        $this->pay_config = [
            // 必要配置
            'app_id'             => config('wechat.payment.default.app_id'),
            'mch_id'             => config('wechat.payment.default.mch_id'),
            'key'                => config('wechat.payment.default.key'),   // API v2 密钥 (注意: 是v2密钥 是v2密钥 是v2密钥)
            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path'          => config('wechat.payment.default.cert_path'), // XXX: 绝对路径！！！！
            'key_path'           => config('wechat.payment.default.key_path'),      // XXX: 绝对路径！！！！
            'notify_url'         => config('wechat.payment.default.notify_url'),     // 你也可以在下单时单独设置来想覆盖它
        ];
    }

    /**
     * 验证输入信息
     * @param  array $rules
     * @return response
     */
    public function validateInput($rules)
    {
        $requests = $this->request->all();

        $validator = Validator::make($requests, $rules);
        if ($validator->fails()) {
            $result = [];
            $messages = $validator->errors()->toArray();

            if ($messages) {
                foreach ($messages as $field => $errors) {
                    foreach ($errors as $error) {
                        $result[] = [
                            'field' => $field,
                            'code' => $error,
                        ];
                    }
                }
            }

            return $this->output(400,$result,'validation error');
        } else {
            $this->validated = array_intersect_key($requests, $rules);
            $this->validated = $requests ;
            return false;
        }
    }

    /**
     * 返回数据
     * @param  int       $code  状态码 0是成功 其他都有错误
     * @param  array     $data
     * @param  string    $msg   错误消息
     * @return json
     */
    protected function output($code='200', $data=array(), $msg='')
    {
        $res = ['code'=>$code,'msg'=>$msg,'data'=>$data];

        if(isset($code) and !$msg)
        {
            $res['msg'] = config('error.'.$code) ? config('error.'.$code) : '未知错误';
        }
        $this->addLog($res, 'API');
        return $res;

    }

    // 记录日志
    protected function addLog($msg, $type)
    {
        return Logs::addLog($msg, $type);
    }

    /**
     * 按照 字母 分组 并 排序
     *
     * @param {Array} $list ; 需要 排序的 数据， 一维数组
     * @param {string} $field ; 排序 需要 依据 的字段，该字段 必须为 拼音
     */
    protected function data_letter_sort($list, $field)
    {
        $resault = array();

        foreach( $list as $key => $val )
        {
            // 添加 # 分组，用来 存放 首字母不能 转为 大写英文的 数据
            $resault['#'] = array();

            // 首字母 转 大写英文
            $letter = strtoupper( substr($val[$field], 0, 1) );

            // 是否 大写 英文 字母
            if( !preg_match('/^[A-Z]+$/', $letter) ){
                $letter = '#';
            }

            // 创建 字母 分组
            if( !array_key_exists($letter, $resault) ){
                $resault[$letter] = array();
            }

            // 字母 分组 添加 数据
            Array_push($resault[$letter], $val);
        }
        // 依据 键名 字母 排序，该函数 返回 boolean
        ksort($resault);

        // 将 # 分组 放到 最后
        $arr_last = $resault['#'];

        unset($resault['#']);

        $resault['#'] = $arr_last;

        return $resault;
    }

    // 天数统计
    protected static function getCountDays($sTime, $eTime)
    {
        $startDt = getdate($sTime);

        $endDt = getdate($eTime);

        $sUTime = mktime(12, 0, 0, $startDt['mon'], $startDt['mday'], $startDt['year']);

        $eUTime = mktime(12, 0, 0, $endDt['mon'], $endDt['mday'], $endDt['year']);

        // 计算日期段内有多少天
        $days = ($eUTime-$sUTime)/86400+1;

        // 保存每天日期
        $date = [];

        for($i=0; $i<$days; $i++)
        {
            $date[] = date('Y-m-d', $sUTime+(86400*$i));
        }

        return $date;
    }

    /*
    $arrF：数组
    $user_count：分成几组
    $group_num：每组多少个
    */
    protected function array_group($arrF,$user_count,$group_num)
    {
        for ($i = 0; $i < $user_count; $i++)
        {
            if ($i == $user_count-1)
            {
                $arrT[] = array_slice($arrF, $i * $group_num );
            }
            else
            {
                $arrT[] = array_slice($arrF, $i * $group_num, $group_num);
            }
        }

        return $arrT;
    }

    protected function getPostMaxSize()
    {
        // 首先判断 post_max_size 设定的值有没有单位，没有则返回其值
        if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
            return (int) $postMaxSize;
        }

        // 有单位时，截取单位，并转换为大写。
        $metric = strtoupper(substr($postMaxSize, -1));
        $postMaxSize = (int) $postMaxSize;

        // 通过字节大写换算，将 post_max_size 设定的值转为字节单位（B）
        switch ($metric) {
            case 'K':
                return $postMaxSize * 1024;
            case 'M':
                return $postMaxSize * 1048576;
            case 'G':
                return $postMaxSize * 1073741824;
            default:
                return $postMaxSize;
        }
    }

    // 清除缓存
    protected function clear()
    {
        Artisan::call('cache:clear');
        Artisan::call('config:clear');
        Artisan::call('route:clear');
        Artisan::call('view:clear');
        Artisan::call('clear-compiled');
        // Artisan::call('modelCache:clear');

        return true;
    }


}
